package com.wanshu.common.aspect;

import com.alibaba.fastjson.JSON;
import com.wanshu.common.annotation.SysLogger;
import com.wanshu.sys.entity.SysLog;
import com.wanshu.sys.mapper.SysLogMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * 系统日志方面
 *
 * @author 张颖辉（zyh）
 * @version 1.0.0
 * @date 2023/06/09
 */
@Component
@Aspect
//@EnableAspectJAutoProxy //如果不在配置类中添加@EnableAspectJAutoProxy，那么所有切面注解是不生效的（springboot因为有自动配置，所以不需要开发人员手工配置@EnableAspectJAutoProxy
public class SysLogAspect {

    @Resource
    private SysLogMapper sysLogMapper;

    @Pointcut("@annotation(com.wanshu.common.annotation.SysLogger)")
    public void pointcut() {
        System.out.println("我是一个切入点");
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long begin = System.currentTimeMillis();
        System.out.println("处理前");
        Object obj = joinPoint.proceed();
        System.out.println("处理后");
        long time = System.currentTimeMillis() - begin;
        saveSysLog(joinPoint, time);
        return obj;
    }

    private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
        SysLog sysLog = new SysLog();
        /* 获得注解中的操作内容 */
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SysLogger sysLogger = method.getAnnotation(SysLogger.class);
        if (sysLogger != null) {
            sysLog.setOperation(sysLogger.value());
        }
        //获得类名+方法名称
        String className = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = method.getName();
        sysLog.setMethod(className + "." + methodName + "()");

        //获取方法参数
        Object[] args = joinPoint.getArgs();
        String params = JSON.toJSONString(args);
        sysLog.setParams(params);

        //方法执行耗时
        sysLog.setTime(time);
        //数据的创建时间
        sysLog.setCreateDate(LocalDateTime.now());
        //记录操作人
        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        String userName = (String) token.getPrincipal();
        sysLog.setUsername(userName);

        sysLogMapper.insert(sysLog);

    }
}
